import hashlib
import json
import uuid

import wmi
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


class Registration:
    def __init__(self):
        self.w_wmi = wmi.WMI()  # 保存为实例变量
        # 组合产品信息和用户信息
        self.product_info = ""
        self.user_info = ""
        # 获取CPU序列号
        self.cpu_serial = str(uuid.getnode())
        # 获取硬盘序列号
        self.disk_serial = self.w_wmi.Win32_DiskDrive()[0].SerialNumber.strip()
        # 获取网卡地址
        self.mac_address = self.w_wmi.Win32_NetworkAdapterConfiguration(IPEnabled=True)[0].MACAddress
        # 组合硬件信息
        self.hardware_info = self.cpu_serial + '|' + self.disk_serial + '|' + self.mac_address
        self.key = ''
        self.iv = ''
        # print(self.hardware_info)
        self.cmf = ''
        self.cmc = ''
        self.cmd = ''

    def get_machine_finger(self):
        # 结构化数据（避免拼接歧义）
        data = {
            "hardware": self.hardware_info,
            "product": self.product_info,
            "user": self.user_info
        }
        plain_text = json.dumps(data)  # 转为JSON字符串

        raw_data = plain_text.encode('utf-8')
        # print('plain_text :', self.hardware_info, plain_text)
        # print('raw_data :', raw_data)
        # 使用SHA-256生成固定长度指纹
        return hashlib.sha256(raw_data).digest()

    def generate_machine_code(self, machine_fingerprint, key, iv):
        """生成机器码（加密后的机器指纹）"""
        cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
        padded_data = pad(bytes.fromhex(machine_fingerprint), AES.block_size)
        encrypted_data = cipher.encrypt(padded_data)
        return encrypted_data.hex()  # 使用bytes.hex()替代binascii.hexlify

    def decode_machine_code(self, machine_code, key, iv):
        """解码机器码（解密验证）"""
        try:
            encrypted_data = bytes.fromhex(machine_code)  # 使用bytes.fromhex()替代binascii.unhexlify
            cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
            decrypted_data = cipher.decrypt(encrypted_data)
            unpadded_data = unpad(decrypted_data, AES.block_size)
            return unpadded_data
        except:
            return None  # 解密失败

    def md5_handle(self, pwd):
        """加密逆向还原"""
        str_pwd = pwd
        m5 = hashlib.md5()
        m5.update(str_pwd.encode('utf-8'))
        return m5.hexdigest()

    def mf(self):
        m = self.get_machine_finger()
        self.cmf = m.hex()  # 使用bytes.hex()替代binascii.hexlify
        return m.hex()

    def mc(self):
        # print(self.cmf, self.key, self.iv)
        self.mf()
        m = self.generate_machine_code(self.cmf, self.key, self.iv)
        self.cmc =m
        return m

    def md(self):
        self.mf()
        self.mc()
        m = self.md5_handle(self.cmc)
        return m

